"""
内容生成器
实现演示文稿内容生成的核心逻辑，包括大纲生成、幻灯片内容生成和视觉元素建议。
"""

import logging
import json
import asyncio
from typing import Dict, List, Optional, Any, Tuple
from datetime import datetime

from ..models import SlideContent, SlideType, PPTRequest
from .ai_service import ai_service
from ..utils.retry_handler import retry_on_failure

logger = logging.getLogger(__name__)


class ContentGenerator:
    """
    内容生成器类
    
    负责生成演示文稿的各种内容，包括大纲、幻灯片内容和视觉元素建议
    """
    
    def __init__(self):
        """初始化内容生成器"""
        self.ai_service = ai_service
        
        # 预定义的幻灯片类型模板
        self.slide_templates = {
            SlideType.TITLE: {
                "structure": ["主标题", "副标题", "作者信息"],
                "visual_suggestions": ["公司Logo", "背景图片", "装饰元素"]
            },
            SlideType.CONTENT: {
                "structure": ["标题", "主要内容点", "支持细节"],
                "visual_suggestions": ["相关图标", "图表", "示意图"]
            },
            SlideType.IMAGE: {
                "structure": ["标题", "图片说明", "关键信息"],
                "visual_suggestions": ["高质量图片", "图片标注", "边框装饰"]
            },
            SlideType.CHART: {
                "structure": ["标题", "图表说明", "数据解读"],
                "visual_suggestions": ["数据图表", "图例", "数据标签"]
            },
            SlideType.CONCLUSION: {
                "structure": ["总结标题", "关键要点", "行动建议"],
                "visual_suggestions": ["总结图标", "要点列表", "联系信息"]
            }
        }
    
    @retry_on_failure(max_retries=3, base_delay=2.0, operation_name="generate_presentation_outline")
    async def generate_presentation_outline(
        self,
        request: PPTRequest,
        session_id: Optional[str] = None
    ) -> Dict[str, Any]:
        """
        生成演示文稿大纲
        
        Args:
            request: PPT生成请求
            session_id: 会话ID
            
        Returns:
            Dict: 包含大纲信息的字典
        """
        try:
            logger.info(f"开始生成演示文稿大纲 - 主题: {request.topic}")
            
            # 构建详细的提示词
            system_prompt = self._build_outline_system_prompt()
            user_prompt = self._build_outline_user_prompt(request)
            
            # 调用AI服务生成大纲
            result = await self.ai_service.generate_presentation_outline(
                topic=request.topic,
                requirements=request.requirements,
                slide_count=request.slide_count,
                session_id=session_id
            )
            
            if not result["success"]:
                return result
            
            # 处理和验证生成的大纲
            outline = result["outline"]
            processed_outline = await self._process_outline(outline, request)
            
            return {
                "success": True,
                "outline": processed_outline,
                "metadata": {
                    "total_slides": len(processed_outline.get("slides", [])),
                    "template_style": request.template_style,
                    "generated_at": datetime.now().isoformat()
                }
            }
            
        except Exception as e:
            logger.error(f"生成演示文稿大纲失败: {e}")
            return {
                "success": False,
                "error": f"生成演示文稿大纲失败: {str(e)}"
            }
    
    @retry_on_failure(max_retries=3, base_delay=1.5, operation_name="generate_slide_content")
    async def generate_slide_content(
        self,
        slide_info: Dict[str, Any],
        context: Dict[str, Any],
        session_id: Optional[str] = None
    ) -> Dict[str, Any]:
        """
        生成单个幻灯片的详细内容
        
        Args:
            slide_info: 幻灯片基本信息
            context: 上下文信息（包括整体主题、前后幻灯片等）
            session_id: 会话ID
            
        Returns:
            Dict: 包含幻灯片内容的字典
        """
        try:
            slide_title = slide_info.get("title", "")
            slide_type = slide_info.get("type", "content")
            slide_number = slide_info.get("slide_number", 1)
            
            logger.info(f"生成幻灯片内容 - 标题: {slide_title}, 类型: {slide_type}")
            
            # 构建上下文信息
            context_info = self._build_slide_context(slide_info, context)
            
            # 调用AI服务生成内容
            result = await self.ai_service.generate_slide_content(
                slide_title=slide_title,
                slide_context=context_info,
                slide_type=slide_type,
                session_id=session_id
            )
            
            if not result["success"]:
                return result
            
            # 处理生成的内容
            slide_data = result["slide"]
            processed_slide = await self._process_slide_content(slide_data, slide_type, slide_number)
            
            return {
                "success": True,
                "slide": processed_slide,
                "metadata": {
                    "slide_number": slide_number,
                    "slide_type": slide_type,
                    "generated_at": datetime.now().isoformat()
                }
            }
            
        except Exception as e:
            logger.error(f"生成幻灯片内容失败: {e}")
            return {
                "success": False,
                "error": f"生成幻灯片内容失败: {str(e)}"
            }
    
    async def generate_visual_suggestions(
        self,
        slide_content: SlideContent,
        template_style: str = "professional"
    ) -> Dict[str, Any]:
        """
        为幻灯片生成视觉元素建议
        
        Args:
            slide_content: 幻灯片内容
            template_style: 模板风格
            
        Returns:
            Dict: 视觉元素建议
        """
        try:
            logger.info(f"生成视觉元素建议 - 幻灯片: {slide_content.title}")
            
            # 基于幻灯片类型获取基础建议
            base_suggestions = self.slide_templates.get(
                slide_content.slide_type, 
                self.slide_templates[SlideType.CONTENT]
            )["visual_suggestions"]
            
            # 基于内容生成具体建议
            content_based_suggestions = await self._generate_content_based_visuals(
                slide_content, template_style
            )
            
            # 合并建议
            all_suggestions = list(set(base_suggestions + content_based_suggestions))
            
            return {
                "success": True,
                "visual_suggestions": all_suggestions,
                "template_style": template_style,
                "slide_type": slide_content.slide_type
            }
            
        except Exception as e:
            logger.error(f"生成视觉元素建议失败: {e}")
            return {
                "success": False,
                "error": f"生成视觉元素建议失败: {str(e)}"
            }
    
    async def optimize_content_flow(
        self,
        slides: List[SlideContent],
        optimization_goals: List[str] = None
    ) -> Dict[str, Any]:
        """
        优化内容流程和格式
        
        Args:
            slides: 幻灯片列表
            optimization_goals: 优化目标列表
            
        Returns:
            Dict: 优化结果
        """
        try:
            logger.info(f"优化内容流程 - 幻灯片数量: {len(slides)}")
            
            optimization_goals = optimization_goals or ["clarity", "flow", "engagement"]
            optimized_slides = []
            
            for i, slide in enumerate(slides):
                # 为每个幻灯片生成优化建议
                optimization_context = {
                    "slide_position": i + 1,
                    "total_slides": len(slides),
                    "previous_slide": slides[i-1].title if i > 0 else None,
                    "next_slide": slides[i+1].title if i < len(slides)-1 else None,
                    "optimization_goals": optimization_goals
                }
                
                optimized_slide = await self._optimize_single_slide(slide, optimization_context)
                optimized_slides.append(optimized_slide)
            
            return {
                "success": True,
                "optimized_slides": optimized_slides,
                "optimization_summary": {
                    "total_slides": len(optimized_slides),
                    "optimization_goals": optimization_goals,
                    "optimized_at": datetime.now().isoformat()
                }
            }
            
        except Exception as e:
            logger.error(f"优化内容流程失败: {e}")
            return {
                "success": False,
                "error": f"优化内容流程失败: {str(e)}"
            }
    
    def _build_outline_system_prompt(self) -> str:
        """构建大纲生成的系统提示词"""
        return """你是一个专业的演示文稿内容策划专家。你的任务是根据用户提供的主题和要求，创建一个结构化、逻辑清晰的演示文稿大纲。

核心要求：
1. 大纲应该有清晰的逻辑流程，从引入到结论
2. 每个幻灯片都应该有明确的目的和价值
3. 内容应该适合目标受众，专业且易于理解
4. 考虑演示的时间限制和重点突出
5. 确保内容的连贯性和完整性

返回格式要求：
- 使用JSON格式
- 包含演示文稿标题和幻灯片列表
- 每个幻灯片包含：标题、类型、主要内容点、演讲者备注

幻灯片类型说明：
- title: 标题页
- content: 内容页
- image: 图片展示页
- chart: 图表数据页
- conclusion: 总结页"""
    
    def _build_outline_user_prompt(self, request: PPTRequest) -> str:
        """构建大纲生成的用户提示词"""
        prompt = f"""请为以下演示文稿创建详细大纲：

主题：{request.topic}
幻灯片数量：{request.slide_count}
模板风格：{request.template_style}
"""
        
        if request.requirements:
            prompt += f"特殊要求：{request.requirements}\n"
        
        prompt += """
请确保：
1. 第一张是标题页，最后一张是总结页
2. 内容按逻辑顺序组织
3. 每张幻灯片的内容点不超过5个
4. 提供简洁但有用的演讲者备注
5. 返回标准JSON格式

JSON格式示例：
{
  "title": "演示文稿标题",
  "slides": [
    {
      "slide_number": 1,
      "title": "幻灯片标题",
      "type": "title",
      "content": ["主要内容点"],
      "notes": "演讲者备注"
    }
  ]
}"""
        
        return prompt
    
    def _build_slide_context(self, slide_info: Dict[str, Any], context: Dict[str, Any]) -> str:
        """构建幻灯片生成的上下文信息"""
        context_parts = [
            f"演示文稿主题：{context.get('presentation_topic', '')}",
            f"当前幻灯片：第{slide_info.get('slide_number', 1)}张",
            f"幻灯片类型：{slide_info.get('type', 'content')}",
            f"总幻灯片数：{context.get('total_slides', 10)}"
        ]
        
        if context.get('previous_slide'):
            context_parts.append(f"前一张幻灯片：{context['previous_slide']}")
        
        if context.get('next_slide'):
            context_parts.append(f"后一张幻灯片：{context['next_slide']}")
        
        if context.get('template_style'):
            context_parts.append(f"模板风格：{context['template_style']}")
        
        return "\n".join(context_parts)
    
    async def _process_outline(self, outline: Dict[str, Any], request: PPTRequest) -> Dict[str, Any]:
        """处理和验证生成的大纲"""
        processed_outline = {
            "title": outline.get("title", request.topic),
            "slides": []
        }
        
        slides = outline.get("slides", [])
        for i, slide in enumerate(slides):
            processed_slide = {
                "slide_number": i + 1,
                "title": slide.get("title", f"幻灯片 {i + 1}"),
                "type": slide.get("type", "content"),
                "content": slide.get("content", []),
                "notes": slide.get("notes", "")
            }
            processed_outline["slides"].append(processed_slide)
        
        return processed_outline
    
    async def _process_slide_content(
        self, 
        slide_data: Dict[str, Any], 
        slide_type: str, 
        slide_number: int
    ) -> SlideContent:
        """处理生成的幻灯片内容，转换为SlideContent对象"""
        
        # 确定幻灯片类型
        try:
            slide_type_enum = SlideType(slide_type)
        except ValueError:
            slide_type_enum = SlideType.CONTENT
        
        # 创建SlideContent对象
        slide_content = SlideContent(
            title=slide_data.get("title", f"幻灯片 {slide_number}"),
            content=slide_data.get("content", []),
            slide_type=slide_type_enum,
            visual_elements=slide_data.get("visual_elements", []),
            notes=slide_data.get("notes"),
            slide_number=slide_number
        )
        
        return slide_content
    
    async def _generate_content_based_visuals(
        self, 
        slide_content: SlideContent, 
        template_style: str
    ) -> List[str]:
        """基于内容生成视觉元素建议"""
        suggestions = []
        
        # 基于内容关键词生成建议
        content_text = " ".join(slide_content.content)
        
        # 简单的关键词匹配逻辑
        visual_keywords = {
            "数据": ["数据图表", "统计图", "柱状图"],
            "流程": ["流程图", "步骤图", "时间线"],
            "比较": ["对比图", "表格", "并列图"],
            "趋势": ["趋势图", "折线图", "增长图"],
            "结构": ["组织图", "结构图", "层次图"],
            "地理": ["地图", "位置图", "区域图"]
        }
        
        for keyword, visuals in visual_keywords.items():
            if keyword in content_text:
                suggestions.extend(visuals)
        
        # 基于模板风格调整建议
        if template_style == "creative":
            suggestions.extend(["创意图标", "艺术元素", "色彩装饰"])
        elif template_style == "minimal":
            suggestions.extend(["简洁图标", "线条元素", "留白设计"])
        elif template_style == "corporate":
            suggestions.extend(["商务图标", "专业图表", "企业元素"])
        
        return list(set(suggestions))
    
    async def _optimize_single_slide(
        self, 
        slide: SlideContent, 
        context: Dict[str, Any]
    ) -> SlideContent:
        """优化单个幻灯片的内容"""
        
        # 这里可以实现更复杂的优化逻辑
        # 目前返回原始内容，后续可以扩展
        optimized_content = slide.content.copy()
        
        # 简单的内容优化：确保每个要点不超过一定长度
        max_length = 80
        optimized_content = [
            content[:max_length] + "..." if len(content) > max_length else content
            for content in optimized_content
        ]
        
        # 创建优化后的幻灯片
        optimized_slide = SlideContent(
            title=slide.title,
            content=optimized_content,
            slide_type=slide.slide_type,
            visual_elements=slide.visual_elements,
            notes=slide.notes,
            slide_number=slide.slide_number
        )
        
        return optimized_slide


# 全局内容生成器实例
content_generator = ContentGenerator()